package top.itaso.lib.common;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @Author: dengfu.su
 * @CreateDate: 2022/2/8
 */
public class AppUtils {
    private static final String TAG = "AppUtils";

    /**
     * 判断指定包名的 App 是否有安装
     *
     * @param context
     * @param pkgName
     * @return true-已安装，false-未安装或者已卸载
     */
    public static boolean isAppInstalled(Context context, String pkgName) {
        PackageManager pm = context.getPackageManager();
        try {
            return pm.getApplicationInfo(pkgName != null ? pkgName : context.getPackageName(), 0).enabled;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取 APP 的版本号：versionName
     *
     * @param context
     * @param pkgName
     * @return versionName
     */
    public static String getAppVersionName(Context context, String pkgName) {
        PackageManager pm = context.getPackageManager();
        try {
            PackageInfo packageInfo = pm.getPackageInfo(pkgName != null ? pkgName : context.getPackageName(), 0);
            return packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return "0.0.1";
    }

    /**
     * 获取 APP 的版本号：versionCode
     *
     * @param context
     * @param pkgName
     * @return versionCode
     */
    public static long getVersionCode(Context context, String pkgName) {
        PackageManager pm = context.getPackageManager();
        try {
            PackageInfo packageInfo = pm.getPackageInfo(pkgName != null ? pkgName : context.getPackageName(), 0);
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
                return packageInfo.versionCode;
            } else {
                return packageInfo.getLongVersionCode();
            }

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 0L;
    }

    /**
     * android.os.Build.VERSION_CODES#O 开始，只返回调用者自己的服务
     *
     * @param context
     * @param className
     * @return
     */
    public static boolean isServiceWorked(Context context, String className) {
        ActivityManager myManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        ArrayList<ActivityManager.RunningServiceInfo> runningService = (ArrayList<ActivityManager.RunningServiceInfo>) myManager.getRunningServices(30);
        for (int i = 0; i < runningService.size(); i++) {
            if (runningService.get(i).service.getClassName().equals(className)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 比较目标版本与源版本是否更新
     *
     * @param curVer 如：2023.10.31.19.18.0
     * @param tarVer 如：2023.12.8.11.28.0
     * @return true-tarVer 版本比 curVer 版本新，false-tarVer 版本没有比 curVer 版本新（包含相同）
     */
    public static boolean compareVersion(String curVer, String tarVer) {
        if (TextUtils.isEmpty(curVer)) {
            return false;
        }
        String[] curVerSpilt = curVer.split("\\.");

        if (TextUtils.isEmpty(tarVer)) {
            return false;
        }
        String[] tarVerSpilt = tarVer.split("\\.");

        if (curVerSpilt.length != tarVerSpilt.length) {//版本号以 . 做切割，长度不同时不匹配新旧，直接当做异常版本，结果为不允许
            return false;
        }
        for (int i = 0; i < tarVerSpilt.length; i++) {
            try {
                //cur:2023.10.31.19.18.0
                //target:2023.12.8.11.28.0
                if (Integer.parseInt(tarVerSpilt[i]) != Integer.parseInt(curVerSpilt[i])) {
                    return Integer.parseInt(tarVerSpilt[i]) > Integer.parseInt(curVerSpilt[i]);
                }
            } catch (Exception exception) {
                Log.e("compareVersion", "compareVersion: >>>>>>tarVerSpilt[" + i + "]=" + tarVerSpilt[i] + ",curVerSpilt[" + i + "]=" + curVerSpilt[i] + ",e=", exception);
            }
        }
        return false;

    }


    /**
     * Return the applications' information.
     *
     * @return the applications' information
     */
    @NonNull
    public static List<AppEntity> getAppEntities(Context context) {
        List<AppEntity> list = new ArrayList<>();
        PackageManager pm = context.getPackageManager();
        if (pm == null) {
            return list;
        }
        List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
        for (PackageInfo pi : installedPackages) {
            AppEntity ai = getBean(pm, pi);
            if (ai == null) continue;
            list.add(ai);
        }
        return list;
    }

    private static AppEntity getBean(final PackageManager pm, final PackageInfo pi) {
        if (pi == null) {
            return null;
        }
        String versionName = pi.versionName;
        int versionCode = pi.versionCode;
        String packageName = pi.packageName;
        ApplicationInfo ai = pi.applicationInfo;
        long installTime = pi.firstInstallTime;
        long updateTime = pi.lastUpdateTime;
        if (ai == null) {
            return new AppEntity(packageName, "", null, "", versionName, versionCode, false, installTime, updateTime);
        }
        String name = ai.loadLabel(pm).toString();
        Drawable icon = ai.loadIcon(pm);
        String packagePath = ai.sourceDir;
        boolean isSystem = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0;
        return new AppEntity(packageName, name, icon, packagePath, versionName, versionCode, isSystem, installTime, updateTime);
    }


    public static class AppEntity {
        private String packageName;//包名
        private String name;//应用名
        private Drawable icon;
        private String installPath;
        private String versionName;
        private int versionCode;
        private boolean isSystem;
        private long installTime;//安装时间
        private long updateTime;//更新时间

        public Drawable getIcon() {
            return icon;
        }

        public void setIcon(final Drawable icon) {
            this.icon = icon;
        }

        public boolean isSystem() {
            return isSystem;
        }

        public void setSystem(final boolean isSystem) {
            this.isSystem = isSystem;
        }

        public String getPackageName() {
            return packageName;
        }

        public void setPackageName(final String packageName) {
            this.packageName = packageName;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public String getInstallPath() {
            return installPath;
        }

        public void setInstallPath(final String installPath) {
            this.installPath = installPath;
        }

        public int getVersionCode() {
            return versionCode;
        }

        public void setVersionCode(final int versionCode) {
            this.versionCode = versionCode;
        }

        public String getVersionName() {
            return versionName;
        }

        public void setVersionName(final String versionName) {
            this.versionName = versionName;
        }

        public long getInstallTime() {
            return installTime;
        }

        public void setInstallTime(long installTime) {
            this.installTime = installTime;
        }

        public long getUpdateTime() {
            return updateTime;
        }

        public void setUpdateTime(long updateTime) {
            this.updateTime = updateTime;
        }

        public AppEntity(String packageName, String name, Drawable icon, String installPath, String versionName, int versionCode, boolean isSystem, long installTime, long updateTime) {
            this.packageName = packageName;
            this.name = name;
            this.icon = icon;
            this.installPath = installPath;
            this.versionName = versionName;
            this.versionCode = versionCode;
            this.isSystem = isSystem;
            this.installTime = installTime;
            this.updateTime = updateTime;
        }

        @Override
        @NonNull
        public String toString() {
            return "{" +
                    "\n    pkg name: " + getPackageName() +
                    "\n    app icon: " + getIcon() +
                    "\n    app name: " + getName() +
                    "\n    app path: " + getInstallPath() +
                    "\n    app v name: " + getVersionName() +
                    "\n    app v code: " + getVersionCode() +
                    "\n    is system: " + isSystem() +
                    "\n}";
        }
    }
}
